
<!DOCTYPE HTML>
<html lang="" >
    <head>
        <meta charset="UTF-8">
        <meta content="text/html; charset=utf-8" http-equiv="Content-Type">
        <title>Kubernetes Basics · GitBook笔记</title>
        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
        <meta name="description" content="">
        <meta name="generator" content="GitBook 3.2.3">
        <meta name="author" content="chenjiebin">
        
        
    
    <link rel="stylesheet" href="../../../../gitbook/style.css">

    
            
                
                <link rel="stylesheet" href="../../../../gitbook/gitbook-plugin-prism/prism.css">
                
            
                
                <link rel="stylesheet" href="../../../../gitbook/gitbook-plugin-search-pro/search.css">
                
            
                
                <link rel="stylesheet" href="../../../../gitbook/gitbook-plugin-expandable-chapters-small/expandable-chapters-small.css">
                
            
                
                <link rel="stylesheet" href="../../../../gitbook/gitbook-plugin-splitter/splitter.css">
                
            
                
                <link rel="stylesheet" href="../../../../gitbook/gitbook-plugin-anchor-navigation-ex/style/plugin.css">
                
            
                
                <link rel="stylesheet" href="../../../../gitbook/gitbook-plugin-code/plugin.css">
                
            
                
                <link rel="stylesheet" href="../../../../gitbook/gitbook-plugin-fontsettings/website.css">
                
            
        

    

    
        
    
        
    
        
    
        
    
        
    
        
    

        
    
    
    <meta name="HandheldFriendly" content="true"/>
    <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
    <meta name="apple-mobile-web-app-capable" content="yes">
    <meta name="apple-mobile-web-app-status-bar-style" content="black">
    <link rel="apple-touch-icon-precomposed" sizes="152x152" href="../../../../gitbook/images/apple-touch-icon-precomposed-152.png">
    <link rel="shortcut icon" href="../../../../gitbook/images/favicon.ico" type="image/x-icon">

    
    <link rel="next" href="../../../java/java.html" />
    
    
    <link rel="prev" href="../kubernetes.html" />
    

    </head>
    <body>
        
<div class="book">
    <div class="book-summary">
        
            
<div id="book-search-input" role="search">
    <input type="text" placeholder="Type to search" />
</div>

            
                <nav role="navigation">
                


<ul class="summary">
    
    

    

    
        
        
    
        <li class="chapter " data-level="1.1" data-path="../../../../">
            
                <a href="../../../../">
            
                    
                    Introduction
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.2" data-path="../kubernetes.html">
            
                <a href="../kubernetes.html">
            
                    
                    Kubernetes英文教程
            
                </a>
            

            
            <ul class="articles">
                
    
        <li class="chapter " data-level="1.2.1" data-path="../kubernetes.html">
            
                <a href="../kubernetes.html#concepts">
            
                    
                    Kubernetes Concepts
            
                </a>
            

            
            <ul class="articles">
                
    
        <li class="chapter " data-level="1.2.1.1" data-path="../concepts/overview.html">
            
                <a href="../concepts/overview.html">
            
                    
                    Kubernetes Overview
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.2.1.2" data-path="../concepts/components.html">
            
                <a href="../concepts/components.html">
            
                    
                    Kubernetes Components
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.2.1.3" data-path="../concepts/nodes.html">
            
                <a href="../concepts/nodes.html">
            
                    
                    Kubernetes Nodes
            
                </a>
            

            
        </li>
    

            </ul>
            
        </li>
    
        <li class="chapter " data-level="1.2.2" data-path="../kubernetes.html">
            
                <a href="../kubernetes.html#tutorial">
            
                    
                    Kubernetes Tutorial
            
                </a>
            

            
            <ul class="articles">
                
    
        <li class="chapter active" data-level="1.2.2.1" data-path="kubernetes-basics.html">
            
                <a href="kubernetes-basics.html">
            
                    
                    Kubernetes Basics
            
                </a>
            

            
        </li>
    

            </ul>
            
        </li>
    

            </ul>
            
        </li>
    
        <li class="chapter " data-level="1.3" data-path="../../../java/java.html">
            
                <a href="../../../java/java.html">
            
                    
                    Java基础知识
            
                </a>
            

            
            <ul class="articles">
                
    
        <li class="chapter " data-level="1.3.1" data-path="../../../java/java-summary.html">
            
                <a href="../../../java/java-summary.html">
            
                    
                    Java_Summary
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.3.2" data-path="../../../java/java-jvm.html">
            
                <a href="../../../java/java-jvm.html">
            
                    
                    Java_JVM
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.3.3" data-path="../../../java/effectiveJava.html">
            
                <a href="../../../java/effectiveJava.html">
            
                    
                    effectiveJava
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.3.4" data-path="../../../java/design-pattern.html">
            
                <a href="../../../java/design-pattern.html">
            
                    
                    设计模式
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.3.5" data-path="../../../java/JavaTest.html">
            
                <a href="../../../java/JavaTest.html">
            
                    
                    JavaTest
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.3.6" data-path="../../../java/myframe.html">
            
                <a href="../../../java/myframe.html">
            
                    
                    MyFrame
            
                </a>
            

            
        </li>
    

            </ul>
            
        </li>
    
        <li class="chapter " data-level="1.4" data-path="../../../database/database.html">
            
                <a href="../../../database/database.html">
            
                    
                    数据库基础知识
            
                </a>
            

            
            <ul class="articles">
                
    
        <li class="chapter " data-level="1.4.1" data-path="../../../database/mysql.html">
            
                <a href="../../../database/mysql.html">
            
                    
                    MySQL
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.4.2" data-path="../../../database/redis.html">
            
                <a href="../../../database/redis.html">
            
                    
                    Redis
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.4.3" data-path="../../../database/kingbase.html">
            
                <a href="../../../database/kingbase.html">
            
                    
                    KingBase
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.4.4" data-path="../../../database/polardb.html">
            
                <a href="../../../database/polardb.html">
            
                    
                    PolarDB
            
                </a>
            

            
        </li>
    

            </ul>
            
        </li>
    
        <li class="chapter " data-level="1.5" data-path="../../../system/system.html">
            
                <a href="../../../system/system.html">
            
                    
                    环境配置工具
            
                </a>
            

            
            <ul class="articles">
                
    
        <li class="chapter " data-level="1.5.1" data-path="../../../system/nodejs.html">
            
                <a href="../../../system/nodejs.html">
            
                    
                    Node.js
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.5.2" data-path="../../../system/gitbook.html">
            
                <a href="../../../system/gitbook.html">
            
                    
                    Gitbook
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.5.3" data-path="../../../system/linux.html">
            
                <a href="../../../system/linux.html">
            
                    
                    Linux
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.5.4" data-path="../../../system/kylin.html">
            
                <a href="../../../system/kylin.html">
            
                    
                    麒麟系统
            
                </a>
            

            
        </li>
    

            </ul>
            
        </li>
    
        <li class="chapter " data-level="1.6" data-path="../../../tool/tool.html">
            
                <a href="../../../tool/tool.html">
            
                    
                    开发工具介绍
            
                </a>
            

            
            <ul class="articles">
                
    
        <li class="chapter " data-level="1.6.1" data-path="../../../tool/docker.html">
            
                <a href="../../../tool/docker.html">
            
                    
                    Docker
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.2" data-path="../../../tool/idea.html">
            
                <a href="../../../tool/idea.html">
            
                    
                    Idea
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.3" data-path="../../../tool/maven.html">
            
                <a href="../../../tool/maven.html">
            
                    
                    Maven
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.4" data-path="../../../tool/gradle.html">
            
                <a href="../../../tool/gradle.html">
            
                    
                    Gradle
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.5" data-path="../../../framework/kubernate.html">
            
                <a href="../../../framework/kubernate.html">
            
                    
                    Kubernetes
            
                </a>
            

            
        </li>
    

            </ul>
            
        </li>
    

    

    <li class="divider"></li>

    <li>
        <a href="https://www.gitbook.com" target="blank" class="gitbook-link">
            Published with GitBook
        </a>
    </li>
</ul>


                </nav>
            
        
    </div>

    <div class="book-body">
        
            <div class="body-inner">
                
                    

<div class="book-header" role="navigation">
    

    <!-- Title -->
    <h1>
        <i class="fa fa-circle-o-notch fa-spin"></i>
        <a href="../../../.." >Kubernetes Basics</a>
    </h1>
</div>




                    <div class="page-wrapper" tabindex="-1" role="main">
                        <div class="page-inner">
                            
<div id="book-search-results">
    <div class="search-noresults">
    
                                <section class="normal markdown-section">
                                
                                <div id="anchor-navigation-ex-navbar"><i class="fa fa-navicon"></i><ul><li><span class="title-icon "></span><a href="#kubernetes-basics"><b>1. </b>Kubernetes Basics</a></li><ul><li><span class="title-icon "></span><a href="#what-can-kubernetes-do-for-you"><b>1.1. </b>What can Kubernetes do for you?</a></li></ul><li><span class="title-icon "></span><a href="#create-a-cluster"><b>2. </b>Create a Cluster</a></li><ul><li><span class="title-icon "></span><a href="#kubernetes-clusters"><b>2.1. </b>Kubernetes Clusters</a></li><li><span class="title-icon "></span><a href="#cluster-diagram"><b>2.2. </b>Cluster Diagram</a></li></ul><li><span class="title-icon "></span><a href="#deploy-an-app"><b>3. </b>Deploy an App</a></li><ul><li><span class="title-icon "></span><a href="#kubernetes-deployments"><b>3.1. </b>Kubernetes Deployments</a></li><li><span class="title-icon "></span><a href="#deploying-your-first-app-on-kubernetes"><b>3.2. </b>Deploying your first app on Kubernetes</a></li><li><span class="title-icon "></span><a href="#kubectl-basics"><b>3.3. </b>kubectl basics</a></li><li><span class="title-icon "></span><a href="#deploy-an-app_1"><b>3.4. </b>Deploy an app</a></li><li><span class="title-icon "></span><a href="#view-the-app"><b>3.5. </b>View the app</a></li></ul><li><span class="title-icon "></span><a href="#explore-your-app"><b>4. </b>Explore Your App</a></li><ul><li><span class="title-icon "></span><a href="#kubernetes-pods"><b>4.1. </b>Kubernetes Pods</a></li><li><span class="title-icon "></span><a href="#kubernetes-nodes"><b>4.2. </b>Kubernetes Nodes</a></li><li><span class="title-icon "></span><a href="#troubleshooting-with-kubectl"><b>4.3. </b>Troubleshooting with kubectl</a></li><ul><li><span class="title-icon "></span><a href="#check-application-configuration"><b>4.3.1. </b>Check application configuration</a></li><li><span class="title-icon "></span><a href="#show-the-app-in-the-terminal"><b>4.3.2. </b>show the app in the terminal</a></li><li><span class="title-icon "></span><a href="#view-the-container-logs"><b>4.3.3. </b>View the container logs</a></li><li><span class="title-icon "></span><a href="#executing-command-on-the-container"><b>4.3.4. </b>Executing command on the container</a></li></ul></ul><li><span class="title-icon "></span><a href="#expose-your-app-publicly"><b>5. </b>Expose Your App Publicly</a></li><ul><li><span class="title-icon "></span><a href="#overview-of-kubernetes-services"><b>5.1. </b>Overview of Kubernetes Services</a></li><li><span class="title-icon "></span><a href="#services-and-labels"><b>5.2. </b>Services and Labels</a></li><ul><li><span class="title-icon "></span><a href="#step1-creating-a-new-service"><b>5.2.1. </b>Step1: Creating a new Service</a></li><li><span class="title-icon "></span><a href="#step2-using-labels"><b>5.2.2. </b>Step2: Using labels</a></li><li><span class="title-icon "></span><a href="#step3-deleting-a-service"><b>5.2.3. </b>Step3: Deleting a Service</a></li></ul></ul><li><span class="title-icon "></span><a href="#scale-your-app"><b>6. </b>Scale Your App</a></li><ul><li><span class="title-icon "></span><a href="#scaling-an-application"><b>6.1. </b>Scaling an application</a></li><li><span class="title-icon "></span><a href="#scaling-a-deployment"><b>6.2. </b>scaling a Deployment</a></li><li><span class="title-icon "></span><a href="#load-balancing"><b>6.3. </b>Load Balancing</a></li><li><span class="title-icon "></span><a href="#scale-down"><b>6.4. </b>Scale Down</a></li></ul><li><span class="title-icon "></span><a href="#update-your-app"><b>7. </b>Update Your App</a></li><ul><li><span class="title-icon "></span><a href="#updating-an-application"><b>7.1. </b>Updating an application</a></li><li><span class="title-icon "></span><a href="#update-the-version-of-the-app"><b>7.2. </b>Update the version of the app</a></li><li><span class="title-icon "></span><a href="#verify-an-update"><b>7.3. </b>Verify an update</a></li><li><span class="title-icon "></span><a href="#roll-back-an-update"><b>7.4. </b>Roll back an update</a></li></ul></ul></div><a href="#kubernetes-basics" id="anchorNavigationExGoTop"><i class="fa fa-arrow-up"></i></a><h1 id="kubernetes-basics"><a name="kubernetes-basics" class="anchor-navigation-ex-anchor" href="#kubernetes-basics"><i class="fa fa-link" aria-hidden="true"></i></a>1. Kubernetes Basics</h1>
<p>This tutorial provides a walkthrough of the basics of the Kubernetes cluster
orchestration system. Each module contains some background information on
major Kubernetes features and concepts, and a tutorial for you to follow along.</p>
<p>Using the tutorials, you can learn to:</p>
<ul>
<li>Deploy a containerized application on a cluster.</li>
<li>Scale the deployment.</li>
<li>Update the containerized application with a new software version.</li>
<li>Debug the containerized application.</li>
</ul>
<h2 id="what-can-kubernetes-do-for-you"><a name="what-can-kubernetes-do-for-you" class="anchor-navigation-ex-anchor" href="#what-can-kubernetes-do-for-you"><i class="fa fa-link" aria-hidden="true"></i></a>1.1. What can Kubernetes do for you?</h2>
<p>With modern web services, users except applications to be available 24/7,
and developers except to deploy new versions of those applications several
times a day. Containerization helps package software to serve these goals,
enabling applications to be released and updated without downtime. Kubernetes
helps you make sure those containerized applications run where and when you
want, and helps them find the resources and tools they need to work.
Kubernetes is a production-ready, open source platform designed with Google&apos;s
accumulated experience in container orchestration, combined with best-of-bread
ideas from the community.</p>
<h1 id="create-a-cluster"><a name="create-a-cluster" class="anchor-navigation-ex-anchor" href="#create-a-cluster"><i class="fa fa-link" aria-hidden="true"></i></a>2. Create a Cluster</h1>
<p>Objectives</p>
<ul>
<li>Learn what a Kubernetes cluster is.</li>
<li>Learn what Minikube is.</li>
<li>Start a Kubernetes cluster on your computer.</li>
</ul>
<h2 id="kubernetes-clusters"><a name="kubernetes-clusters" class="anchor-navigation-ex-anchor" href="#kubernetes-clusters"><i class="fa fa-link" aria-hidden="true"></i></a>2.1. Kubernetes Clusters</h2>
<p><strong>Kubernetes coordinates a highly available cluster of computers that are
connected to work as a single unit.</strong> The abstraction in Kubernetes allow
you to deploy containerized applications to a cluster without tying them
specifically to individual machines. To make use of this new model of
deployment, applications need to be packaged in a way that decouples them
form individual hosts: they need to be containerized. Containerized
application are more flexible and available than in past deployment models,
where application were installed directly onto specific machines as packages
deeply integrated into the host. <strong>Kubernetes automates the distribution and
scheduling of application containers across a cluster in more efficient way.</strong>
Kubernetes is an open-source platform and is production-ready.</p>
<p>A Kubernetes cluster consists of two types of resource:</p>
<ul>
<li>The Control Plane coordinates the cluster</li>
<li>Nodes are the workers that run applications</li>
</ul>
<h2 id="cluster-diagram"><a name="cluster-diagram" class="anchor-navigation-ex-anchor" href="#cluster-diagram"><i class="fa fa-link" aria-hidden="true"></i></a>2.2. Cluster Diagram</h2>
<p><img src="https://kubernetes.io/docs/tutorials/kubernetes-basics/public/images/module_01_cluster.svg" alt="module_01_cluster.svg"></p>
<p>The Control Plane is responsible for managing the cluster. The Control
Plane coordinates all activities in your cluster, such as scheduling
applications, maintaining application&apos;s desired state, scaling applications,
and rolling out new updates.</p>
<p>A node is a VM or a physical computer that serves as a worker machine in a
Kubernetes cluster. Each node has a Kubelet, which is an agent for managing
the node and communicating with the Kubernetes control plane. The node should
also have tools for handling container operations, such as containerd or
CRI-O. A Kubernetes cluster that handles production traffic should have a
minimum of three nodes because if one node goes down, both an etcd member
and a control plane instance are lost, and redundancy is compromised. You
can mitigate this risk by adding more control plane nodes.</p>
<blockquote>
<p>Control Planes manage the cluster and the Nodes that are used to host the
running applications.</p>
</blockquote>
<p>When you deploy applications on Kubernetes, you tell the control plane to
start the application containers. The control plane schedules the containers
to run on the cluster&apos;s nodes. Node-level components, such as the kubelet,
communicate with the control plane using the Kubernetes API, which the
control plane exposes. End users can also use the Kubernetes API directly
to interact with the cluster.</p>
<p>A Kubernetes cluster can be deployed on either physical or virtual machines.
To get started with Kubernetes development, you can use Minikube. Minikube
is a lightweight Kubernetes implementation that creates a VM on your local
machine and deploys a simple cluster containing only one node. Minikube is
available for Linux, macOS, and Windows system. The Minikube CLI provides
basic bootstrapping operations for working with your cluster, including
start, stop, status, and delete.</p>
<h1 id="deploy-an-app"><a name="deploy-an-app" class="anchor-navigation-ex-anchor" href="#deploy-an-app"><i class="fa fa-link" aria-hidden="true"></i></a>3. Deploy an App</h1>
<p>Objectives</p>
<ul>
<li>Learn about applications Deployments.</li>
<li>Deploy your first app on Kubernetes with kubectl.</li>
</ul>
<h2 id="kubernetes-deployments"><a name="kubernetes-deployments" class="anchor-navigation-ex-anchor" href="#kubernetes-deployments"><i class="fa fa-link" aria-hidden="true"></i></a>3.1. Kubernetes Deployments</h2>
<p>Once you have a running Kubernetes cluster, you can deploy your containerized
applications on top of it. To do so, you create a Kubernetes Deployment.
The Deployment instructs Kubernetes how to create and update instances of your
application. Once you&apos;ve created a Deployment, the Kubernetes control plane
schedulers the application instance included in that Deployment to run on
individual Nodes in the cluster.</p>
<p>Once the application instances are created, a Kubernetes Deployment controller
continuously monitors those instance. If the Node hosting an instance goes
down or is deleted, the Deployment controller replaces the instance with an
instance on another Node in the cluster. This provides a self-healing
mechanism to address machine failure or maintenance.</p>
<p>In a pre-orchestration world, installation scripts would often be used to
start applications, but they did not allow recovery from machine failure.
By both creating your application instances and keeping them running across
Nodes, Kubernetes Deployments provide a fundamentally different approach
to application management.</p>
<blockquote>
<p>A Deployment is responsible for creating and updating instances of your application.</p>
</blockquote>
<h2 id="deploying-your-first-app-on-kubernetes"><a name="deploying-your-first-app-on-kubernetes" class="anchor-navigation-ex-anchor" href="#deploying-your-first-app-on-kubernetes"><i class="fa fa-link" aria-hidden="true"></i></a>3.2. Deploying your first app on Kubernetes</h2>
<p><img src="https://kubernetes.io/docs/tutorials/kubernetes-basics/public/images/module_02_first_app.svg" alt="module_02_first_app.svg"></p>
<p>You can create and manage a Deployment by using the Kubernetes command line
interface, kubectl. Kubectl uses the Kubernetes API to interact with the
cluster. In this module, you&apos;ll learn the most common kubectl commands
needed to create Deployments that run your applications on a Kubernetes
cluster.</p>
<p>When you create a Deployment, you&apos;ll need to specify the container image
for your application and the number of replicas that you want to run.
You can change that information later by updating your Deployment; 
Modules <a href="#scale-your-app">6</a> and <a href="#update-your-app">7</a> of the bootcamp 
discuss how you can scale and update your Deployments.</p>
<blockquote>
<p>Applications need to be packaged into one of the supported container
formats in order to be deployed on Kubernetes.</p>
</blockquote>
<p>For your first Deployment, you&apos;ll use a hello-node application packaged
in a Docker container that uses UGINX to echo back all the requests.
(If you didn&apos;t already try creating a hello-node application and deploying
it using a container, you can do that first by following the instructions
from the Hello Minikube tutorial).</p>
<p>You will need to have installed kubectl as well. If you need to install it,
visit install tools.</p>
<p>Now that you know what Deployments are, let&apos;s deploy our fist app!</p>
<h2 id="kubectl-basics"><a name="kubectl-basics" class="anchor-navigation-ex-anchor" href="#kubectl-basics"><i class="fa fa-link" aria-hidden="true"></i></a>3.3. kubectl basics</h2>
<p>The common format of a kubectl command is: <code>kubectl action resource</code></p>
<p>This performs the specified action (like create, describe or delete) on the
specified resource (like node or deployment). You can use <code>--help</code> after
the subcommand to get additional info about possible parameters (for example:
<code>kubectl get nodes --help</code>).</p>
<p>Check that kubectl is configured to talk to your cluster, by running the
<code>kubectl version</code> command.</p>
<p>Check that kubectl is installed, and you can see both the client and the
server versions.</p>
<p>To view the nodes in the cluster, run the <code>kubectl get nodes</code> command.</p>
<p>You see the available nodes. Later, Kubernetes will choose where to deploy
our application based on Node available resources.</p>
<h2 id="deploy-an-app_1"><a name="deploy-an-app_1" class="anchor-navigation-ex-anchor" href="#deploy-an-app_1"><i class="fa fa-link" aria-hidden="true"></i></a>3.4. Deploy an app</h2>
<p>Let&apos;s deploy our first app on Kubernetes with the <code>kubectl create deployment</code>
command. We need to provide the deployment name and app image location (include
the full repository url for images hosted outside Docker Hub).</p>
<pre class="language-"><code class="lang-shell">kubectl create deployment demo <span class="token parameter variable">--image</span><span class="token operator">=</span>hhitzhl/kubernetes-bootcamp:v1
</code></pre>
<p>Great! You just deployed your first application by creating a deployment.
This performed a new things for you:</p>
<ul>
<li>searched for a suitable node where an instance of the application could
be run (we have only 1 available node)</li>
<li>scheduled the application to run on that Node</li>
<li>configured the cluster to reschedule the instance on a new Node when needed</li>
</ul>
<p>To list your deployments use the <code>kubectl get deployments</code> command:</p>
<pre class="language-"><code class="lang-shell">kubectl get deployments
</code></pre>
<p>We see that there is 1 deployment running a single instance of your app.
The instance is running inside a container on your node.</p>
<h2 id="view-the-app"><a name="view-the-app" class="anchor-navigation-ex-anchor" href="#view-the-app"><i class="fa fa-link" aria-hidden="true"></i></a>3.5. View the app</h2>
<p>Pods that are running inside Kubernetes are running on a private, isolated
network. By default, they are visible from other pods and services within
the same Kubernetes cluster, but not outside that network. When we use
<code>kubectl</code>, we&apos;re interacting through an API endpoint to communicate with
our application.</p>
<p>We will cover other options on how to expose your application outside the
Kubernetes cluster later, in <a href="#explore-your-app-publicly">Module 5</a>.
Also, as a basic tutorial, we&apos;re not explaining what Pods are in any detail here,
it will cover in later topics.</p>
<p>The <code>kubectl proxy</code> command can create a proxy that will forward communications
into the cluster-wide, private network. The proxy can be terminated by 
pressing control-C and won&apos;t show any output while its running.</p>
<p><strong>You need to open a second terminal window to run the proxy.</strong></p>
<pre class="language-"><code class="lang-shell">kubectl proxy
</code></pre>
<p>We now have a connection between our host (the terminal) and the Kubernetes
cluster. The proxy enables direct access to the API from these terminals.</p>
<p>You can see all those APIs hosted through the proxy endpoint. For example,
we can query the version directly through the API using the <code>curl</code> command,
also you can access by the Edge.</p>
<pre class="language-"><code class="lang-shell"><span class="token function">curl</span> http://localhost:8001/version
</code></pre>
<p>The API server will automatically create an endpoint for each pod, based on
the pod name, that is also accessible through the proxy. 
First you can get the Pod Name.</p>
<pre class="language-"><code class="lang-shell">kubectl get pods
</code></pre>
<p>The result as follows:</p>
<pre class="language-"><code class="lang-text">NAME                    READY   STATUS    RESTARTS   AGE
demo-69cbb7466c-6q6vf   1/1     Running   0          10m
</code></pre>
<p>Then you can access the Pod through the proxied API, by running:</p>
<pre class="language-"><code class="lang-shell"><span class="token function">curl</span> http://localhost:8001/api/v1/namespaces/default/pods/demo-69cbb7466c-6q6vf
</code></pre>
<h1 id="explore-your-app"><a name="explore-your-app" class="anchor-navigation-ex-anchor" href="#explore-your-app"><i class="fa fa-link" aria-hidden="true"></i></a>4. Explore Your App</h1>
<p>Objectives</p>
<ul>
<li>Learn about Kubernetes Pods.</li>
<li>Learn about Kubernetes Nodes.</li>
<li>Troubleshot deployed applications.</li>
</ul>
<h2 id="kubernetes-pods"><a name="kubernetes-pods" class="anchor-navigation-ex-anchor" href="#kubernetes-pods"><i class="fa fa-link" aria-hidden="true"></i></a>4.1. Kubernetes Pods</h2>
<p>When you created a Deployment in Module <a href="#create-a-cluster">2</a>, Kubernetes
created a <strong>Pod</strong> to host your applications instance. A pod is a Kubernetes
abstraction that represents a group of one or more application containers
(such as Docker), and some shared resources for those containers.
Those resources include:</p>
<ul>
<li>Shared storage, as Volumes</li>
<li>Networking, as a unique cluster IP address</li>
<li>Information about how to run each container, such as the container image
version or specific ports to use</li>
</ul>
<p>A Pod models an application-specific &quot;logical host&quot; and can contain different
application containers which are relatively tightly coupled. For example,
a Pod might include both the container with you Node.js app as well as
a different container that feeds the data to be published by the Node.js
webserver. The containers in a Pod share an IP Address and port space,
are always co-located and co-scheduled, and run in a shared context on
the same Node.</p>
<p>Pods are the atomic unit on the Kubernetes platform. When we create a
Deployment on Kubernetes, that Deployment creates Pods with containers
inside them (as opposed to creating containers directly). Each Pod is
tied to the Node where it is scheduled, and remains there until termination
(according to restart policy) or deletion. In case of a Node failure,
identical Pods are scheduled on other available Nodes in the cluster.</p>
<blockquote>
<p>A Pod is a group of one or more application containers (such as Docker)
  and includes shared storage (volumes), IP address and information
  about how to run them.</p>
</blockquote>
<p><img src="https://kubernetes.io/docs/tutorials/kubernetes-basics/public/images/module_03_pods.svg" alt="module_03_pods.svg"></p>
<h2 id="kubernetes-nodes"><a name="kubernetes-nodes" class="anchor-navigation-ex-anchor" href="#kubernetes-nodes"><i class="fa fa-link" aria-hidden="true"></i></a>4.2. Kubernetes Nodes</h2>
<p>A Pod always runs on a Node. A Node is a worker machine in Kubernetes and
may be either a virtual or physical machine, depending on the cluster.
Each Node is managed by the control plane. A Node can have multiple pods,
and the Kubernetes control plane automatically handles scheduling the pods
across the Nodes in the cluster. The control plane&apos;s automatic scheduling
takes into account available resources on each Node.</p>
<p>Every Kubernetes Node runs at least:</p>
<ul>
<li>Kubelet, a process responsible for communication between the Kubernetes
control plane and the Node, it manages the Pods and the containers
running on a machine.</li>
<li>A containing runtime (like Docker) responsible for pulling the container
image from a registry, unpacking the container, and running the application.</li>
</ul>
<blockquote>
<p>Containers should only be scheduled together in a single Pod if they are
  tightly coupled and need to share resources such as disk.</p>
</blockquote>
<p><img src="https://kubernetes.io/docs/tutorials/kubernetes-basics/public/images/module_03_nodes.svg" alt="module_03_nodes.svg"></p>
<h2 id="troubleshooting-with-kubectl"><a name="troubleshooting-with-kubectl" class="anchor-navigation-ex-anchor" href="#troubleshooting-with-kubectl"><i class="fa fa-link" aria-hidden="true"></i></a>4.3. Troubleshooting with kubectl</h2>
<p>In Module <a href="#deploy-an-app">3</a>, you used the kubectl command-line interface.
You&apos;ll continue to use it in Module 4 to get information about deployed
applications and their environments. The most common operations can be
done with the following kubectl subcommands:</p>
<ul>
<li><code>kubectl get</code> - list resources</li>
<li><code>kubectl describe</code> - show detailed information about a resource</li>
<li><code>kubectl logs</code> - print the logs from a container in a pod</li>
<li><code>kubectl exec</code> - execute a command on a container in a pod</li>
</ul>
<p>You can use these commands to see when applications were deployed, what
their current statuses are, where they are running and what their
configurations are.</p>
<p>Now that we know more about our cluster components and the command line,
let&apos;s explore our application.</p>
<blockquote>
<p>A node is a worker machine in Kubernetes and may be a VM or physical
  machine, depending on the cluster. Multiple Pods can run on one Node.</p>
</blockquote>
<h3 id="check-application-configuration"><a name="check-application-configuration" class="anchor-navigation-ex-anchor" href="#check-application-configuration"><i class="fa fa-link" aria-hidden="true"></i></a>4.3.1. Check application configuration</h3>
<p>Let&apos;s verify that the application we deployed in the previous scenario is
running. We&apos;ll use the <code>kubectl get</code> command and look for existing Pods:</p>
<pre class="language-"><code class="lang-shell">kubectl get pods
</code></pre>
<p>If no pods are running, please wait a couple of seconds and list the Pods
again. You can continue once you see one Pod running.</p>
<p>Next, to view that what containers are inside that Pod and what images are
used to build those containers we run the <code>kubectl describe pods</code> command:</p>
<pre class="language-"><code class="lang-shell">kubectl describe pods
</code></pre>
<p>We see here details about the Pod&apos;s container: IP address, the ports used
and a list of events related to the lifecycle of the Pod.</p>
<p>The output of the <code>describe</code> subcommand is extensive and covers some concepts
that we didn&apos;t explain yet, but don&apos;t worry, they will become familiar by
the end of this bootcamp.</p>
<p>Note: the <code>describe</code> subcommand can be used to get detailed information
about most of the Kubernetes primitives, including Nodes, Pods, and Deployments.
The describe output is designed to be human-readable, not to be scripted against.</p>
<h3 id="show-the-app-in-the-terminal"><a name="show-the-app-in-the-terminal" class="anchor-navigation-ex-anchor" href="#show-the-app-in-the-terminal"><i class="fa fa-link" aria-hidden="true"></i></a>4.3.2. show the app in the terminal</h3>
<p>Recall that Pods are running in an isolated, private network - so we need
to proxy access to them, so we can debug and interact with them. To do this,
we&apos;ll use the <code>kubectl proxy</code> command to run a proxy in a <strong>second terminal</strong>.
Open a new terminal window, and in that new terminal, run:</p>
<pre class="language-"><code class="lang-shell">kubectl proxy
</code></pre>
<p>Now again, we&apos;ll get the Pod name and query that pod directly through the
proxy. To get the Pod name:</p>
<pre class="language-"><code class="lang-shell">kubectl get pods
</code></pre>
<p>The results as follows:</p>
<pre class="language-"><code class="lang-text">NAME                    READY   STATUS    RESTARTS   AGE
demo-69cbb7466c-6q6vf   1/1     Running   0          10m
</code></pre>
<p>To see the output of our application, run a <code>curl</code> request or visit by Edge:</p>
<pre class="language-"><code class="lang-shell"><span class="token function">curl</span> http://localhost:8001/api/v1/namespaces/default/pods/demo-69cbb7466c-6q6vf:8080/proxy
</code></pre>
<p>The URL is the route to the API of the Pod.</p>
<h3 id="view-the-container-logs"><a name="view-the-container-logs" class="anchor-navigation-ex-anchor" href="#view-the-container-logs"><i class="fa fa-link" aria-hidden="true"></i></a>4.3.3. View the container logs</h3>
<p>Anything that the application would normally send to standard output
becomes logs for the container within the Pod. We can retrieve these
logs using the <code>kubectl logs</code> command:</p>
<pre class="language-"><code class="lang-shell">kubectl logs demo-69cbb7466c-6q6vf
</code></pre>
<p>Note: We don&apos;t need to specify the container name, because we only have
one container inside the pod.</p>
<h3 id="executing-command-on-the-container"><a name="executing-command-on-the-container" class="anchor-navigation-ex-anchor" href="#executing-command-on-the-container"><i class="fa fa-link" aria-hidden="true"></i></a>4.3.4. Executing command on the container</h3>
<p>We can execute commands directly on the container once the Pod is up and
running. For this, we use the <code>exec</code> subcommand and use the name of the Pod
as a parameter. Let&apos;s list the environment variables:</p>
<pre class="language-"><code class="lang-shell">kubectl <span class="token builtin class-name">exec</span> demo-69cbb7466c-6q6vf -- <span class="token function">env</span>
</code></pre>
<p>Again, it&apos;s worth mentioning that the name of the container itself can be
omitted since we only have a single container in the Pod.</p>
<p>Next let&apos;s start a bash session in the Pod&apos;s container:</p>
<pre class="language-"><code class="lang-shell">kubectl <span class="token builtin class-name">exec</span> <span class="token parameter variable">-ti</span> demo-69cbb7466c-6q6vf -- <span class="token function">bash</span>
</code></pre>
<p>We have now an open console on the container where we run our NodeJS application.
The source code of the app is the server.js file:</p>
<pre class="language-"><code class="lang-shell"><span class="token function">cat</span> server.js
</code></pre>
<p>You can check that the application is up by running a <code>curl</code> command:</p>
<pre class="language-"><code class="lang-shell"><span class="token function">curl</span> http://localhost:8080
</code></pre>
<p>Note: here we used <code>localhost</code> because we executed the command inside
the NodeJS Pod. If you cannot connect to localhost:8080, check to make sure
you have run the <code>kubectl exec</code> command and are launching the command from
within the Pod</p>
<p>To close you container connection, type <code>exit</code>.</p>
<h1 id="expose-your-app-publicly"><a name="expose-your-app-publicly" class="anchor-navigation-ex-anchor" href="#expose-your-app-publicly"><i class="fa fa-link" aria-hidden="true"></i></a>5. Expose Your App Publicly</h1>
<p>Objectives</p>
<ul>
<li>Learn about a Service in Kubernetes</li>
<li>Understand how labels and selectors relate to a Service</li>
<li>Expose an application outside a Kubernetes cluster using a Service</li>
</ul>
<h2 id="overview-of-kubernetes-services"><a name="overview-of-kubernetes-services" class="anchor-navigation-ex-anchor" href="#overview-of-kubernetes-services"><i class="fa fa-link" aria-hidden="true"></i></a>5.1. Overview of Kubernetes Services</h2>
<p>Kubernetes Pods are mortal. Pods have a lifecycle. When a worker node dies,
the Pods running on the Node are also lost. A ReplicaSet might then dynamically
drive the cluster back to the desired stat via the creation of new Pods to
keep your application running. As another example, consider an image-processing
backend with 3 replicas. Those replicas are exchangeable; the front-end
system should not care about backend replicas or even if a Pod is lost and
recreated. That said, each Pod in a Kubernetes cluster has a unique IP
address, even Pods on the same Node, so there needs to be a way of
automatically reconciling changes among Pods so that your applications
continue to function.</p>
<p>A Service in Kubernetes is an abstraction which defines a logical set of
Pods and a policy by which to access them. Services enables a loose coupling
between dependent Pods. A Service is defined using YAML or JSON, like all
Kubernetes object manifests. The set of Pods targeted by a Service is
usually determined by label selector (see below for why you might want
a Service without including a <code>selector</code> in the spec).</p>
<p>Although each Pod has a unique IP address, those IPs are not exposed outside
the cluster without a Service. Services allow your applications to receive
traffic. Services can be exposed in different ways by specifying a <code>type</code>
in the <code>spec</code> of the Service:</p>
<ul>
<li>ClusterIP (default) - Exposes the Service on an internal IP in the cluster.
This type makes the Service only reachable from within the cluster.</li>
<li>NodePort - Exposes the Service on the same port of each selected Node in the
cluster using NAT. Makes a Services accessible from outside the cluster
using <code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>NodeIP</span><span class="token punctuation">&gt;</span></span>:<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>NodePort</span><span class="token punctuation">&gt;</span></span></code>. Superset of ClusterIP.</li>
<li>LoadBalancer - Creates an external load balancer in the current cloud (if
supported) and assigns a fixed, external IP to the Service. Superset of NodePort.</li>
<li>ExternalName - Maps the Service to the contents of the <code>externalName</code>
field (e.g. <code>foo.bar.example.com</code>), by returning a <code>CNAME</code> record with
its value. No proxying of any kind is set up. This type requires v1.7
or higher of <code>kube-dns</code>, or CoreDNS version 0.0.8 or higher.</li>
</ul>
<p>Additionally, note that there some use cases with Services that involve
not defining a <code>selector</code> in the spec. A service created without <code>selector</code>
will also not create the corresponding Endpoints object. This allows users
to manually map a Service to specific endpoints. Another possibility why
there may be no selector is you are strictly using <code>type: ExternalName</code>.</p>
<blockquote>
<p>A Kubernetes Service is an abstraction layer defines a logical set of
  Pods and enables external traffic exposoure, load balancing and service
  discovery for those Pods.</p>
</blockquote>
<h2 id="services-and-labels"><a name="services-and-labels" class="anchor-navigation-ex-anchor" href="#services-and-labels"><i class="fa fa-link" aria-hidden="true"></i></a>5.2. Services and Labels</h2>
<p>A Service routes traffic across a set of Pods. Services are the abstraction
that allows pods to die and replicate in Kubernetes without impacting your
application. Discovery and routing among dependent Pods (such as the frontend
and backend components in an application) are handled by Kubernetes Services.</p>
<p>Services match a set of Pods using labels nad selectors, a grouping primitive
that allows logical operation on objects in Kubernetes. Labels are key/value
pairs attached to objects and cna be used in any number of ways:</p>
<ul>
<li>Designate objects for development, test, and production</li>
<li>Embed version tags</li>
<li>Classify an object using tags</li>
</ul>
<p><img src="https://kubernetes.io/docs/tutorials/kubernetes-basics/public/images/module_04_labels.svg" alt="module_04_labels.svg"></p>
<p>Labels can be attached to objects at creation time or later on. They can
be modified at any time. Let&apos;s expose our application now using a Service
and apply some labels.</p>
<h3 id="step1-creating-a-new-service"><a name="step1-creating-a-new-service" class="anchor-navigation-ex-anchor" href="#step1-creating-a-new-service"><i class="fa fa-link" aria-hidden="true"></i></a>5.2.1. Step1: Creating a new Service</h3>
<p>Let&apos;s verify that our application is running. We&apos;ll use the <code>kubectl get</code>
command and look for existing Pods:</p>
<pre class="language-"><code class="lang-shell">kubectl get pods
</code></pre>
<p>If no Pods are running then it means the objects from the previous tutorials
were cleaned up. In this case, go back and recreate the deployment from the
<a href="#create-a-cluster">Using kubectl to create a Deployment</a> tutorial. 
Please wait a couple of seconds and list the Pods again. You can continue
once you see the one Pod running.</p>
<p>Next, let&apos;s list the current Services from our cluster.</p>
<pre class="language-"><code class="lang-shell">kubectl get services
</code></pre>
<p>We have a Service called <code>kubernetes</code> that is created by default when
minikube starts the cluster. To create a new service and expose it to
external traffic we&apos;ll use the expose command with NodePort as parameter.</p>
<pre class="language-"><code class="lang-shell">kubectl expose deployment/demo <span class="token parameter variable">--type</span><span class="token operator">=</span><span class="token string">&quot;NodePort&quot;</span> <span class="token parameter variable">--port</span> <span class="token number">8080</span>
</code></pre>
<p>Let&apos;s run again the <code>get services</code> subcommand:</p>
<pre class="language-"><code class="lang-shell">kubectl get services
</code></pre>
<p>We have now a running Service called demo. Here we see that the Service
received a unique cluster-IP, an internal port and an external-IP
(the IP of the Node).</p>
<p>To find out what port was opened externally (for the <code>type: NodePort</code> Service)
we&apos;ll run the <code>describe service</code> subcommand:</p>
<pre class="language-"><code class="lang-shell">kubectl describe services/demo
</code></pre>
<p>Get the Node port of Service.</p>
<pre class="language-"><code class="lang-shell">kubectl get services
</code></pre>
<p>The result as follows:</p>
<pre class="language-"><code class="lang-text">NAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
demo         NodePort    10.110.67.173   &lt;none&gt;        8080:30243/TCP   6s
kubernetes   ClusterIP   10.96.0.1       &lt;none&gt;        443/TCP          6d5h
</code></pre>
<p>Then we can test that the app is exposed outside the cluster using <code>curl</code>,
the IP address if the Node and the externally exposed port:</p>
<pre class="language-"><code class="lang-shell"><span class="token function">curl</span> http://localhost:30243/
</code></pre>
<p>And we get a response from the server. The Service is exposed.</p>
<h3 id="step2-using-labels"><a name="step2-using-labels" class="anchor-navigation-ex-anchor" href="#step2-using-labels"><i class="fa fa-link" aria-hidden="true"></i></a>5.2.2. Step2: Using labels</h3>
<p>The Deployment created automatically a label for our Pod. With the
<code>describe deployment</code> subcommand you can see the name (the <code>key</code>)
of that label:</p>
<pre class="language-"><code class="lang-shell">kubectl describe deployment
</code></pre>
<p>Let&apos;s use this label to query our list of Pods. We&apos;ll use the <code>kubectl get pods</code>
command with <code>-l</code> as a parameter, followed by the label values:</p>
<pre class="language-"><code class="lang-shell">kubectl get pods <span class="token parameter variable">-l</span> <span class="token assign-left variable">app</span><span class="token operator">=</span>demo
</code></pre>
<p>You can do the same to list the existing Services:</p>
<pre class="language-"><code class="lang-shell">kubectl get services <span class="token parameter variable">-l</span> <span class="token assign-left variable">app</span><span class="token operator">=</span>demo
</code></pre>
<p>We can get the name of the Pod. To apply a new label we use the <code>label</code>
subcommand followed by the object type, object name and the new label:</p>
<pre class="language-"><code class="lang-shell"><span class="token comment"># kubectl get pods</span>
<span class="token comment"># pod name: demo-69cbb7466c-6q6vf</span>
kubectl label pods demo-69cbb7466c-6q6vf <span class="token assign-left variable">version</span><span class="token operator">=</span>v1
</code></pre>
<p>This will apply a new label to our Pod (we pinned the application version
to the Pod), and we can check it with the describe pod command:</p>
<pre class="language-"><code class="lang-shell">kubectl describe pods demo-69cbb7466c-6q6vf
</code></pre>
<p>We see here that the label is attached now to our Pod. And we can query now
the list of pods using the new label:</p>
<pre class="language-"><code class="lang-shell">kubectl get pods <span class="token parameter variable">-l</span> <span class="token assign-left variable">version</span><span class="token operator">=</span>v1
</code></pre>
<p>And we see the Pod.</p>
<h3 id="step3-deleting-a-service"><a name="step3-deleting-a-service" class="anchor-navigation-ex-anchor" href="#step3-deleting-a-service"><i class="fa fa-link" aria-hidden="true"></i></a>5.2.3. Step3: Deleting a Service</h3>
<p>To delete Services you can use the <code>delete service</code> subcommand. Labels
can be used also here:</p>
<pre class="language-"><code class="lang-shell">kubectl delete <span class="token function">service</span> <span class="token parameter variable">-l</span> <span class="token assign-left variable">app</span><span class="token operator">=</span>demo
</code></pre>
<p>Confirm that the Service is gone:</p>
<pre class="language-"><code class="lang-shell">kubectl get services
</code></pre>
<p>This confirms that our Service was removed. To confirm that route is not
exposed anymore you can <code>curl</code> the previously exposed IP and port:</p>
<pre class="language-"><code class="lang-shell"><span class="token function">curl</span> http://localhost:30243/
</code></pre>
<p>This proves that the application is not reachable anymore from outside of
the cluster. You can confirm that the app is still running with a <code>curl</code>
from inside the pod:</p>
<pre class="language-"><code class="lang-shell">kubectl <span class="token builtin class-name">exec</span> <span class="token parameter variable">-ti</span> demo-69cbb7466c-6q6vf  -- <span class="token function">curl</span> http://localhost:8080
</code></pre>
<p>We see here that the application is up. This is because the Deployment
is managing the application. To shut down the application, you would need
to delete the Deployment as well.</p>
<h1 id="scale-your-app"><a name="scale-your-app" class="anchor-navigation-ex-anchor" href="#scale-your-app"><i class="fa fa-link" aria-hidden="true"></i></a>6. Scale Your App</h1>
<p>Objectives</p>
<ul>
<li>Scale an app using the kubectl</li>
</ul>
<h2 id="scaling-an-application"><a name="scaling-an-application" class="anchor-navigation-ex-anchor" href="#scaling-an-application"><i class="fa fa-link" aria-hidden="true"></i></a>6.1. Scaling an application</h2>
<p>Previously we created a Deployment, and then exposed it publicly via a
Service. The Deployment created only one Pod for running our application.
When traffic increases, we will need to scale the application to keep up
with user demand.</p>
<p><em>Scaling</em> is accomplished by changing the number of replicas in a Deployment</p>
<blockquote>
<p>You can create from the start a Deployment with multiple instances using
  the --replicas parameter for the kubectl create deployment command</p>
</blockquote>
<p><img src="https://kubernetes.io/docs/tutorials/kubernetes-basics/public/images/module_05_scaling1.svg" alt="module_05_scaling1.svg"></p>
<p>Scaling out a Deployment will ensure new Pods are created and scheduled to
Nodes with available resources. Scaling will increase the number of Pods
to the new desired state. Kubernetes also supports autoscaling of Pods,
but it is outside of the scope of this tutorial. Scaling to zero is also
possible, and it will terminate all Pods of the specified Deployment.</p>
<p>Running multiple instances of an application will require a way to distribute
the traffic to all of them. Services have an integrated load-balancer that
will distribute network traffic to all Pods of an exposed Deployment.
Services will monitor continuously the running Pods using endpoints,
to ensure the traffic is sent only to available Pods.</p>
<blockquote>
<p>Scaling is accomplished by changing the number of replicas in a Deployment.</p>
</blockquote>
<p>Once you have multiple instance of an application running, you would be
able to do Rolling updates without downtime. We&apos;ll cover that in the next
section of the tutorial. Now, let&apos;s go to the terminal and scale our application.</p>
<h2 id="scaling-a-deployment"><a name="scaling-a-deployment" class="anchor-navigation-ex-anchor" href="#scaling-a-deployment"><i class="fa fa-link" aria-hidden="true"></i></a>6.2. scaling a Deployment</h2>
<p>To list your Deployments, use the <code>get deployment</code> subcommand:</p>
<pre class="language-"><code class="lang-shell">kubectl get deployments
</code></pre>
<p>The output should be similar to:</p>
<pre class="language-"><code class="lang-text">NAME   READY   UP-TO-DATE   AVAILABLE   AGE
demo   1/1     1            1           38m
</code></pre>
<p>We should have one Pod. If not, run the command again. This shows:</p>
<ul>
<li><em>NAME</em> lists the names of the Deployments in the cluster </li>
<li><em>READY</em> shows the ratio of CURRENT/DESIRED replicas</li>
<li><em>UP-TO-DATE</em> displays the number of replicas that have benn updated to achieve the desired state</li>
<li><em>AVAILABLE</em> displays how many replicas of the application are available to your users</li>
<li><em>AGE</em> displays the amount of time that the application has been running</li>
</ul>
<p>To see the ReplicaSet created by the Deployment, run:</p>
<pre class="language-"><code class="lang-shell">kubectl get rs
</code></pre>
<p>Notice that the name of the ReplicaSet is always formatted as
[DEPLOYMENT-NAME]-[RANDOM-STRING]. The random string is randomly
generated and uses the <em>pod-template-hash</em> as a seed.</p>
<p>Two important columns of this output are:</p>
<ul>
<li><em>DESIRED</em> displays the desired number of replicas of the application,
which you define when you create the Deployment. This is the desired state.</li>
<li><em>CURRENT</em> displays how many replicas are currently running.</li>
</ul>
<p>Next, let&apos;s scale the Deployment to 3 replicas. We&apos;ll use the <code>kubectl scale</code>
command, followed by the Deployment type, name and desired number of instances:</p>
<pre class="language-"><code class="lang-shell">kubectl scale deployment/demo <span class="token parameter variable">--replicas</span><span class="token operator">=</span><span class="token number">3</span>
</code></pre>
<p>To list your Deployments once again, use <code>get deployments</code>:</p>
<pre class="language-"><code class="lang-shell">kubectl get deployments
</code></pre>
<p>The change was applied, and we have 3 instances of the application available.
Next, let&apos;s check if the number of Pods changed:</p>
<pre class="language-"><code class="lang-shell">kubectl get pods <span class="token parameter variable">-o</span> wide
</code></pre>
<p>There are 3 Pods now, with different IP addresses. The change was registered
in the Deployment events log. To check that, use describe subcommand:</p>
<pre class="language-"><code class="lang-shell">kubectl describe deployment/demo
</code></pre>
<p>You can also view in the output of this command that there are 3 replicas now.</p>
<h2 id="load-balancing"><a name="load-balancing" class="anchor-navigation-ex-anchor" href="#load-balancing"><i class="fa fa-link" aria-hidden="true"></i></a>6.3. Load Balancing</h2>
<p>Let&apos;s check that the Service is load-balancing the traffic. To find out
the exposed IP and Port we can use the describe service as we learned
in the previous part of the tutorail:</p>
<pre class="language-"><code class="lang-shell">kubectl describe services/demo
</code></pre>
<p>Then we can get the Node port of the Deployment. Next, we&apos;ll do a <code>curl</code>
to the exposed IP address and port. Execute the command multiple times:</p>
<pre class="language-"><code class="lang-shell">kubectl get services/demo
<span class="token function">curl</span> http://localhost:30879
</code></pre>
<p>We hit a different Pod with every request. This demonstrates that the
load-balancing is working.</p>
<h2 id="scale-down"><a name="scale-down" class="anchor-navigation-ex-anchor" href="#scale-down"><i class="fa fa-link" aria-hidden="true"></i></a>6.4. Scale Down</h2>
<p>To scale down the Deployment to 2 replicas, run again the <code>scale</code> subcommand:</p>
<pre class="language-"><code class="lang-shell">kubectl scale deployment/demo <span class="token parameter variable">--replicas</span><span class="token operator">=</span><span class="token number">2</span>
</code></pre>
<p>List the Deployments to check if the change was applied with the
<code>get deployments</code> subcommand:</p>
<pre class="language-"><code class="lang-shell">kubectl get deployments
</code></pre>
<p>The number of replicas decreased to 2. List the number of Pods, with <code>get pods</code>:</p>
<pre class="language-"><code class="lang-shell">kubectl get pods <span class="token parameter variable">-o</span> wide
</code></pre>
<p>This confirms that 1 Pods were terminated.</p>
<h1 id="update-your-app"><a name="update-your-app" class="anchor-navigation-ex-anchor" href="#update-your-app"><i class="fa fa-link" aria-hidden="true"></i></a>7. Update Your App</h1>
<p>Objectives</p>
<ul>
<li>Perform a rolling update using kubectl.</li>
</ul>
<h2 id="updating-an-application"><a name="updating-an-application" class="anchor-navigation-ex-anchor" href="#updating-an-application"><i class="fa fa-link" aria-hidden="true"></i></a>7.1. Updating an application</h2>
<p>Users expect applications to be available all the time and developers
are excepted to deploy new versions of them several times a day. In
Kubernetes this is done with rolling updates. <strong>Rolling updates</strong> allow
Deployments&apos; update to take place with zero downtime by incrementally
updating Pods instances with new ones. The new Pods will be scheduled
on Nodes with available resources.</p>
<p>In the previous module we scaled our application to run multiple instances.
This is a requirement for performing updates without affecting application
availability. By default, the maximum number of Pods that can be unavailable
during the update and the maximum number of new Pods that can be created,
is one. Both options can be configured to either numbers or percentages
(of Pods). In Kubernetes, updates are versioned and any Deployment update
can be reverted to a previous (stable) version.</p>
<blockquote>
<p>Rolling updates allow Deployments&apos; update to take place with zero downtime
  by incrementally updating Pods instances with new ones.</p>
</blockquote>
<p><img src="https://kubernetes.io/docs/tutorials/kubernetes-basics/public/images/module_06_rollingupdates4.svg" alt="module_06_rolling_updates4.svg"></p>
<p>Similar to application Scaling, if a Deployment is exposed publicly, the
Service will load-balance the traffic only to available Pods during the 
update. An available Pod is an instance that is available to the users
of the application.</p>
<p>Rolling updates allow the following actions:</p>
<ul>
<li>Promote an application from one environment to another (via container image updates)</li>
<li>Rollback to previous versions</li>
<li>Continuous Integration and Continuous Delivery of applications with zero downtime</li>
</ul>
<blockquote>
<p>If a Deployment is exposed publicly, the Service will load-balance the
  traffic only to available Pods during the update.</p>
</blockquote>
<p>In the following interactive tutorial, we&apos;ll update our application to
a-new version, and also perform a rollback.</p>
<h2 id="update-the-version-of-the-app"><a name="update-the-version-of-the-app" class="anchor-navigation-ex-anchor" href="#update-the-version-of-the-app"><i class="fa fa-link" aria-hidden="true"></i></a>7.2. Update the version of the app</h2>
<p>To list your Deployment, run the <code>get deployment</code> subcommand:</p>
<pre class="language-"><code class="lang-shell">kubectl get deployments
</code></pre>
<p>To list the running Pods, run the <code>get pods</code> subcommand:</p>
<pre class="language-"><code class="lang-shell">kubectl get pods
</code></pre>
<p>To view the current image version of the app, run the <code>describe pods</code>
subcommand and look for the <code>Image</code> field:</p>
<pre class="language-"><code class="lang-shell">kubectl describe pods
</code></pre>
<p>To update the image of the application to version 2, use the <code>set image</code>
subcommand, followed by the deployment name and the new image version:</p>
<pre class="language-"><code class="lang-shell">kubectl <span class="token builtin class-name">set</span> image deployments/demo kubernetes-bootcamp<span class="token operator">=</span>hhitzhl/kubernetes-bootcamp:v2
</code></pre>
<p>The command notified the Deployment to use a different image for your app
and initiated a rolling update. Check the status of the new Pods, and view
the old one terminating with the <code>get pods</code> subcommand:</p>
<pre class="language-"><code class="lang-shell">kubectl get pods
</code></pre>
<h2 id="verify-an-update"><a name="verify-an-update" class="anchor-navigation-ex-anchor" href="#verify-an-update"><i class="fa fa-link" aria-hidden="true"></i></a>7.3. Verify an update</h2>
<p>First, check that the app is running. To find the exposed IP address and
port, run the <code>describe service</code> command:</p>
<pre class="language-"><code class="lang-shell">kubectl describe services/demo
</code></pre>
<h2 id="roll-back-an-update"><a name="roll-back-an-update" class="anchor-navigation-ex-anchor" href="#roll-back-an-update"><i class="fa fa-link" aria-hidden="true"></i></a>7.4. Roll back an update</h2>
<p>Let&apos;s perform another update, and try to deploy an image tagged with <code>v10</code>:</p>
<pre class="language-"><code class="lang-shell">kubectl <span class="token builtin class-name">set</span> image deployments/demo kubernetes-bootcamp<span class="token operator">=</span>hhitzhl/kubernetes-bootcamp:v10
</code></pre>
<p>Use <code>get deployments</code> to see the status of the deployments:</p>
<pre class="language-"><code class="lang-shell">kubectl get deployments
</code></pre>
<p>Notice that the output doesn&apos;t list the desired number of available Pods.
Run the <code>get pods</code> subcommand to list all Pods:</p>
<pre class="language-"><code class="lang-shell">kubectl get pods
</code></pre>
<p>To get more insight into the problem, run the <code>describe pods</code> subcommand:</p>
<pre class="language-"><code class="lang-shell">kubectl describe pods
</code></pre>
<p>In the <code>Events</code> section of the output for the affected Pods, notice that the
<code>v10</code> image version did not exist in the repository.</p>
<p>To roll back the deployment to your last working version, use the 
<code>rollout undo</code> subcommand:</p>
<pre class="language-"><code class="lang-shell">kubectl rollout undo deployments/demo
</code></pre>
<p>The <code>rollout undo</code> command reverts the deployment to the previous known
state (v2 of the image). Updates are versioned, and you can revert to any
previously known state of a Deployment.</p>
<p>Use the <code>get pods</code> subcommand to list the Pods again:</p>
<pre class="language-"><code class="lang-shell">kubeclt get pods
</code></pre>
<p>Three Pods are running. To check the image deployed on these Pods, use
the <code>describe pods</code> subcommand:</p>
<pre class="language-"><code class="lang-shell">kubectl describe pods
</code></pre>
<p>The Deployment is once again using a stable version of the app (v2).
The rollback was successful.</p>
<p>Remember to clean up your local cluster</p>
<pre class="language-"><code class="lang-shell">kubectl delete deployments/demo services/demo
</code></pre>

                                
                                </section>
                            
    </div>
    <div class="search-results">
        <div class="has-results">
            
            <h1 class="search-results-title"><span class='search-results-count'></span> results matching "<span class='search-query'></span>"</h1>
            <ul class="search-results-list"></ul>
            
        </div>
        <div class="no-results">
            
            <h1 class="search-results-title">No results matching "<span class='search-query'></span>"</h1>
            
        </div>
    </div>
</div>

                        </div>
                    </div>
                
            </div>

            
                
                <a href="../kubernetes.html#tutorial" class="navigation navigation-prev " aria-label="Previous page: Kubernetes Tutorial">
                    <i class="fa fa-angle-left"></i>
                </a>
                
                
                <a href="../../../java/java.html" class="navigation navigation-next " aria-label="Next page: Java基础知识">
                    <i class="fa fa-angle-right"></i>
                </a>
                
            
        
    </div>

    <script>
        var gitbook = gitbook || [];
        gitbook.push(function() {
            gitbook.page.hasChanged({"page":{"title":"Kubernetes Basics","level":"1.2.2.1","depth":3,"next":{"title":"Java基础知识","level":"1.3","depth":1,"path":"markdown/java/java.md","ref":"markdown/java/java.md","articles":[{"title":"Java_Summary","level":"1.3.1","depth":2,"path":"markdown/java/java-summary.md","ref":"markdown/java/java-summary.md","articles":[]},{"title":"Java_JVM","level":"1.3.2","depth":2,"path":"markdown/java/java-jvm.md","ref":"markdown/java/java-jvm.md","articles":[]},{"title":"effectiveJava","level":"1.3.3","depth":2,"path":"markdown/java/effectiveJava.md","ref":"markdown/java/effectiveJava.md","articles":[]},{"title":"设计模式","level":"1.3.4","depth":2,"path":"markdown/java/design-pattern.md","ref":"markdown/java/design-pattern.md","articles":[]},{"title":"JavaTest","level":"1.3.5","depth":2,"path":"markdown/java/JavaTest.md","ref":"markdown/java/JavaTest.md","articles":[]},{"title":"MyFrame","level":"1.3.6","depth":2,"path":"markdown/java/myframe.md","ref":"markdown/java/myframe.md","articles":[]}]},"previous":{"title":"Kubernetes Tutorial","level":"1.2.2","depth":2,"anchor":"#tutorial","path":"markdown/document/kubernetes/kubernetes.md","ref":"markdown/document/kubernetes/kubernetes.md#tutorial","articles":[{"title":"Kubernetes Basics","level":"1.2.2.1","depth":3,"path":"markdown/document/kubernetes/tutorial/kubernetes-basics.md","ref":"markdown/document/kubernetes/tutorial/kubernetes-basics.md","articles":[]}]},"dir":"ltr"},"config":{"plugins":["theme-default","prism","-highlight","search-pro","-search","-lunr","expandable-chapters-small","splitter","-sharing","anchor-navigation-ex","code"],"styles":{"ebook":"styles/ebook.css","epub":"styles/epub.css","mobi":"styles/mobi.css","pdf":"styles/pdf.css","print":"styles/print.css","website":"styles/website.css"},"pluginsConfig":{"prism":{},"search-pro":{},"expandable-chapters-small":{},"splitter":{},"anchor-navigation-ex":{"associatedWithSummary":true,"float":{"floatIcon":"fa fa-navicon","level1Icon":"","level2Icon":"","level3Icon":"","showLevelIcon":false},"mode":"float","multipleH1":true,"pageTop":{"level1Icon":"","level2Icon":"","level3Icon":"","showLevelIcon":false},"printLog":false,"showGoTop":true,"showLevel":true},"code":{"copyButtons":true},"fontsettings":{"theme":"white","family":"sans","size":2},"theme-default":{"showLevel":false,"styles":{"ebook":"styles/ebook.css","epub":"styles/epub.css","mobi":"styles/mobi.css","pdf":"styles/pdf.css","print":"styles/print.css","website":"styles/website.css"}}},"theme":"default","author":"chenjiebin","pdf":{"pageNumbers":true,"fontSize":12,"fontFamily":"Arial","paperSize":"a4","chapterMark":"pagebreak","pageBreaksBefore":"/","margin":{"right":62,"left":62,"top":56,"bottom":56}},"structure":{"langs":"LANGS.md","readme":"README.md","glossary":"GLOSSARY.md","summary":"SUMMARY.md"},"pluginConfig":{"prism":{"css":["prismjs/themes/prism-solarizedlight.css"]},"anchor-navigation-ex":{"showLevel":true},"theme-default":{"toggleMenu":false}},"variables":{},"title":"GitBook笔记","gitbook":"*","description":"学习笔记，包含前后端基础知识及框架的学习笔记"},"file":{"path":"markdown/document/kubernetes/tutorial/kubernetes-basics.md","mtime":"2023-12-27T09:56:24.405Z","type":"markdown"},"gitbook":{"version":"3.2.3","time":"2024-02-28T09:32:04.838Z"},"basePath":"../../../..","book":{"language":""}});
        });
    </script>
</div>

        
    <script src="../../../../gitbook/gitbook.js"></script>
    <script src="../../../../gitbook/theme.js"></script>
    
        
        <script src="../../../../gitbook/gitbook-plugin-search-pro/jquery.mark.min.js"></script>
        
    
        
        <script src="../../../../gitbook/gitbook-plugin-search-pro/search.js"></script>
        
    
        
        <script src="../../../../gitbook/gitbook-plugin-expandable-chapters-small/expandable-chapters-small.js"></script>
        
    
        
        <script src="../../../../gitbook/gitbook-plugin-splitter/splitter.js"></script>
        
    
        
        <script src="../../../../gitbook/gitbook-plugin-code/plugin.js"></script>
        
    
        
        <script src="../../../../gitbook/gitbook-plugin-fontsettings/fontsettings.js"></script>
        
    

    </body>
</html>

